package com.adms.shiro;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;

import com.adms.domain.User;
import com.adms.domain.UserMapper;

public class ShiroRealm extends AuthorizingRealm {

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private DefaultWebSessionManager sessionManager;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Session session = SecurityUtils.getSubject().getSession();
		String role = ((User)session.getAttribute("user")).getRole();
		Set<String> roles = new HashSet<>();
		roles.add(role);
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setRoles(roles);
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		Session session = SecurityUtils.getSubject().getSession();
		if(token instanceof WechatUsernamePasswordToken) {
			User loginUser = (User) session.getAttribute("user");
			return new SimpleAuthenticationInfo(loginUser.getUserId(),
					loginUser.getPassword(), ByteSource.Util.bytes(loginUser.getSalt()), getName());
		}
		String phone = (String) token.getPrincipal();
		User user = userMapper.selectByPhone(phone);
		if (user == null) {
			throw new UnknownAccountException(phone+"不存在");
		}
		if(user.getIsLocked()) {
			throw new LockedAccountException(phone+"已锁定");
		}
		//禁止重复登录
		Integer userId = user.getUserId();
		Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
		for(Session s:sessions){
			Object attr = s.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
			if(attr != null) {
				Integer loginUserId = Integer.valueOf(attr.toString());
				if(userId.equals(loginUserId)){ 
					s.setTimeout(0); 
				}
			}
		}
		session.setAttribute("user", user);
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userId,
				user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
		return authenticationInfo;
	}

}